package com.mjf.cjt.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chanjet.openapi.sdk.java.exception.ChanjetApiException;
import com.mjf.cjt.domain.VoucherEntity;
import com.mjf.cjt.mapper.VoucherMapper;
import com.mjf.cjt.service.AsyncTMService;
import com.mjf.cjt.service.TmAccountDicService;
import com.mjf.cjt.service.VoucherService;
import com.mjf.cjt.util.TMUtils;
import com.mjf.cjt.vo.VoucherResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * desc
 * </p>
 *
 *
 * @author chenshoumeng
 * @date 2025/4/11 13:44
 */
@Slf4j
@Service
public class VoucherServiceImpl extends ServiceImpl<VoucherMapper, VoucherEntity> implements VoucherService {

    private static final String SYNC_VOUCHER = "lock:voucher";

    @Autowired
    private AsyncTMService asyncTMService;
    @Autowired
    private TmAccountDicService tmAccountDicService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncVoucher(String start, String end) {
        synchronized (SYNC_VOUCHER) {
            try {
                VoucherResultVO voucherResultVO = asyncTMService.syncVoucher(start, end);
                List<VoucherEntity> voucherEntityList = new ArrayList<>();
                if (ObjectUtil.isNotNull(voucherResultVO) && CollectionUtil.isNotEmpty(voucherResultVO.getRows())) {
                    for (VoucherResultVO.RowInfo rowInfo : voucherResultVO.getRows()) {
                        VoucherEntity voucherEntity = new VoucherEntity();
                        BeanUtil.copyProperties(rowInfo, voucherEntity);
                        if (CollectionUtil.isNotEmpty(rowInfo.getTs())) {
                            try {
                                voucherEntity.setTs(TMUtils.tmTsTimeToString(rowInfo.getTs()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (CollectionUtil.isNotEmpty(rowInfo.getTs2())) {
                            try {
                                voucherEntity.setTs2(TMUtils.tmTsTimeToString(rowInfo.getTs2()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getPostdate())) {
                            try {
                                voucherEntity.setPostdate(TMUtils.tmTsTimeToStr(rowInfo.getPostdate()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getMadedate())) {
                            try {
                                voucherEntity.setMadedate(TMUtils.tmTsTimeToStr(rowInfo.getMadedate()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getAuditeddate())) {
                            try {
                                voucherEntity.setAuditeddate(TMUtils.tmTsTimeToStr(rowInfo.getAuditeddate()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getCreatedtime())) {
                            try {
                                voucherEntity.setCreatedtime(TMUtils.tmTsTimeToStr(rowInfo.getCreatedtime()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getCashierauditdate())) {
                            try {
                                voucherEntity.setCashierauditdate(TMUtils.tmTsTimeToStr(rowInfo.getCashierauditdate()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getInvalidatedate())) {
                            try {
                                voucherEntity.setInvalidatedate(TMUtils.tmTsTimeToStr(rowInfo.getInvalidatedate()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getVoucherdate())) {
                            try {
                                voucherEntity.setVoucherdate(TMUtils.tmTsTimeToStr(rowInfo.getVoucherdate()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getDuedate())) {
                            try {
                                voucherEntity.setDuedate(TMUtils.tmTsTimeToStr(rowInfo.getDuedate()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getBizdate())) {
                            try {
                                voucherEntity.setBizdate(TMUtils.tmTsTimeToStr(rowInfo.getBizdate()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        if (StrUtil.isNotBlank(rowInfo.getBilldate())) {
                            try {
                                voucherEntity.setBilldate(TMUtils.tmTsTimeToStr(rowInfo.getBilldate()));
                            } catch (Exception e) {
                                e.printStackTrace();
                                log.error("解析时间戳异常 {}", e);
                            }
                        }
                        voucherEntityList.add(voucherEntity);
                    }
                    // 查询已存在凭证
                    List<VoucherEntity> list = list(Wrappers.<VoucherEntity>lambdaQuery().in(VoucherEntity::getIdentrydto,
                        voucherEntityList.stream().map(VoucherEntity::getIdentrydto).collect(Collectors.toList())));
                    if (CollectionUtil.isNotEmpty(list)) {
                        // 删除已存在的凭证
                        removeByIds(list.stream().map(VoucherEntity::getVid).collect(Collectors.toList()));
                    }
                    voucherEntityList = new ArrayList<>(voucherEntityList.stream()
                        .collect(Collectors.toMap(
                            VoucherEntity::getIdentrydto,  // key：用哪个字段去重
                            Function.identity(),  // value：保留整对象
                            (v1, v2) -> v1  // 冲突时保留第一个
                        ))
                        .values());
                    saveBatch(voucherEntityList, 500);
                    log.info("同步凭证成功, 共计 {} 条.", voucherEntityList.size());
                }

            } catch (ChanjetApiException e) {
                e.printStackTrace();
                throw new RuntimeException("同步凭证失败.");
            }
        }

    }

}
